package com.mdd.front.controller.ai;

import com.mdd.common.core.AjaxResult;
import com.mdd.common.plugin.ai.AiDriver;
import com.mdd.front.factory.chatAi.ChatBaseOpenAiProxyService;
import com.mdd.front.factory.chatAi.OpenAiProxyServiceFactory;
import com.mdd.common.plugin.ai.response.ChatGptResponse;
import com.mdd.common.util.RedisUtils;
import com.mdd.front.LikeFrontThreadLocal;
import com.mdd.front.service.IAiQuestionRecordService;
import com.mdd.front.service.impl.AiTagServiceImpl;
import com.mdd.front.validate.AiQuestionRecordCreateValidate;
import com.mdd.front.validate.AiTagCreateValidate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jetbrains.annotations.NotNull;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.UUID;

/**
 * @author XYueong
 * @date 2023-12-05
 * @description:
 */
@RestController
@RequestMapping("/api/aiChat")
@Api(tags = "ai交流")
public class AiChatController {
    @Resource
    AiDriver aiDriver;
    @Resource
    IAiQuestionRecordService iAiQuestionRecordService;

    @Deprecated //废弃
    //    @GetMapping("/question")
    @ApiOperation(value = "提问v1")
    public AjaxResult<Object> question(@RequestParam("question") String question) {
        Integer userId = LikeFrontThreadLocal.getUserId();
        try {
            Object key = RedisUtils.get("ai:lock:chatGpt" + userId);
            if (key != null) {
                return AjaxResult.failed("请稍后上个问题还没回答完成");
            }
            RedisUtils.set("ai:lock:chatGpt" + userId, 1);

            ChatGptResponse chatGptResponse = aiDriver.chatGptApi(question, new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890)));

            {//对话数据录入
                AiQuestionRecordCreateValidate userProposed = new AiQuestionRecordCreateValidate();
                userProposed.setUserId(Long.valueOf(userId));
                userProposed.setContent(question);
                userProposed.setType(0L);
                iAiQuestionRecordService.add(userProposed);
                AiQuestionRecordCreateValidate aiAnswer = new AiQuestionRecordCreateValidate();
                aiAnswer.setUserId(Long.valueOf(userId));
                aiAnswer.setType(1L);
                aiAnswer.setContent(chatGptResponse.getChoices().get(0).getMessage().getContent());
                iAiQuestionRecordService.add(aiAnswer);
            }
            return AjaxResult.success(chatGptResponse);
        } catch (Exception e) {
            return AjaxResult.failed("问题回复失败");
        } finally {
            RedisUtils.del("ai:lock:chatGpt" + userId);
        }
    }

    @PostMapping("/question")
    @ApiOperation(value = "提问v2")
    public void question(HttpServletResponse response, @RequestParam("question") String question,String session){
        Integer userId = LikeFrontThreadLocal.getUserId();
        String sessionId = this._createSessionId(userId,session);

        //验锁
        this._checkLock(userId);
        try {
            //设置响应参数
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");
            ServletOutputStream outputStream = response.getOutputStream();
            //这里可以获取到Gpt的回答
            StringBuilder aiAnswerMsg = new StringBuilder();
            ChatBaseOpenAiProxyService proxyService = OpenAiProxyServiceFactory.createProxyService();
            proxyService.createStreamChatCompletion(question, sessionId, outputStream, aiAnswerMsg);
            //记录会话
            this._recordSession(question,aiAnswerMsg.toString(), userId,sessionId);
        } catch (IOException e) {
            throw new IllegalArgumentException("错误 获取响应体失败");
        } finally {
            RedisUtils.del("ai:lock:chatGpt" + userId);
        }
    }

    @Resource
    AiTagServiceImpl aiTagService;
    /**
     * 描述: 生成会话id
     * @author: XYueong
     * @date: 2023/12/7
     */
    private  String _createSessionId(Integer userId,String session) {
        String sessionId;
        if (session==null){
            sessionId =  userId +"_"+ UUID.randomUUID().toString().replace("-","");
            AiTagCreateValidate aiTagCreateValidate =new AiTagCreateValidate();
            aiTagCreateValidate.setTitle(sessionId);
            aiTagCreateValidate.setSessionId(sessionId);
            aiTagCreateValidate.setUserId(userId);
            aiTagService.add(aiTagCreateValidate);
        }else {
             sessionId = userId +"_"+session;
        }
        return sessionId;
    }


    /**
     * 描述: 记录ai会话
     * @author: XYueong
     * @date: 2023/12/7
     */

    private void _recordSession(String question,String  aiAnswerMsg , Integer userId,String sessionId) {
        //对话数据录入
        AiQuestionRecordCreateValidate userProposed = new AiQuestionRecordCreateValidate();
        userProposed.setUserId(Long.valueOf(userId));
        userProposed.setContent(question);
        userProposed.setType(0L);
        userProposed.setSessionId(sessionId);
        iAiQuestionRecordService.add(userProposed);
        AiQuestionRecordCreateValidate aiAnswer = new AiQuestionRecordCreateValidate();
        aiAnswer.setUserId(Long.valueOf(userId));
        aiAnswer.setType(1L);
        aiAnswer.setContent(aiAnswerMsg);
        aiAnswer.setSessionId(sessionId);
        iAiQuestionRecordService.add(aiAnswer);
    }



    /**
     * 描述: 限流锁
     * @author: XYueong
     * @date: 2023/12/7
     */
    private  void _checkLock(Integer userId) {
        Object key = RedisUtils.get("ai:lock:chatGpt" + userId);
        if (key != null) {
            throw new IllegalArgumentException("请稍后上个问题还没回答完成");
        }
        RedisUtils.set("ai:lock:chatGpt" + userId, 1);
    }


}
